package com.ld.admin.util;

import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.jsoup.nodes.Element;

import com.ld.admin.config.SystemStaticParams;
import com.ld.admin.model.system.SysMenuModel;
import com.ld.admin.plugin.cache.PermCacheUtil;
import com.ld.admin.plugin.cache.UrlPermCacheUtil;
import com.ld.common.util.SharedVarsUtil;
import com.ld.shieldsb.common.core.util.StringUtils;
import com.ld.shieldsb.common.web.util.Web;

/**
 * 权限工具类，对一些常用操作进行了聚合
 * 
 * @ClassName PermissionUtil
 * @author <a href="mailto:donggongai@126.com" target="_blank">吕凯</a>
 * @date 2019年6月19日 下午4:26:03
 *
 */
public class PermissionUtil {
    /**
     * 是否检查权限，顶级管理员用户不检查
     * 
     * @Title checkPermission
     * @author 吕凯
     * @date 2019年6月19日 下午4:05:15
     * @param request
     * @return boolean
     */
    public static boolean checkPermission(HttpServletRequest request) {
        Long userId = Web.Util.getSessionUserId(request);
        return userId == null || !userId.equals(SystemStaticParams.TOP_MANAGER_ID); // 非顶级管理员，顶级管理员不判断权限
    }

    /**
     * 获取url在权限中的映射url
     * 
     * @Title getUrlPerm
     * @author 吕凯
     * @date 2019年6月11日 下午1:55:28
     * @param url
     * @return String
     */
    public static String getUrlPerm(String url) {
        return UrlPermCacheUtil.getUrlPerm(url);
    }

    /**
     * 获取url对应的权限model
     * 
     * @Title getPermModleByUrl
     * @author 吕凯
     * @date 2019年6月11日 下午2:03:21
     * @param url
     * @return SysMenuModel
     */
    public static SysMenuModel getPermModleByUrl(String url) {
        return UrlPermCacheUtil.getPermModleByUrl(url);
    }

    /**
     * 根据pageId获取权限model
     * 
     * @Title getPermByPageId
     * @author 吕凯
     * @date 2019年6月19日 下午4:24:55
     * @param pageId
     * @return SysMenuModel
     */
    public static SysMenuModel getPermByPageId(String pageId) {
        return PermCacheUtil.getPermByPageId(pageId);
    }

    /**
     * 从session中获取用户的所有权限id
     * 
     * @Title getUserPermIds
     * @author 吕凯
     * @date 2019年4月13日 上午8:55:54
     * @param session
     * @return Set<String>
     */
    @SuppressWarnings("unchecked")
    public static Set<String> getUserPermIds(HttpSession session) {
        Set<String> userPermIds = (Set<String>) session.getAttribute(SystemStaticParams.SESSION_USER_PERMS_ID);
        return userPermIds;
    }

    /**
     * 从request中获取session中保存的所有权限id
     * 
     * @Title getUserPermIds
     * @author 吕凯
     * @date 2019年9月21日 上午9:19:02
     * @param request
     * @return Set<String>
     */
    public static Set<String> getUserPermIds(HttpServletRequest request) {
        HttpSession session = request.getSession();
        return getUserPermIds(session);
    }

    /**
     * 
     * 检查pageId或dataUrl权限是否存在
     * 
     * @Title checkPerm
     * @author 吕凯
     * @date 2019年9月21日 上午9:21:08
     * @param request
     * @param pageId
     * @param dataUrl
     * @return boolean
     */
    public static boolean checkPerm(HttpServletRequest request, String pageId, String dataUrl) {
        return checkPerm(request, getUserPermIds(request), pageId, dataUrl);
    }

    public static boolean checkUrlPerm(HttpServletRequest request, String dataUrl) {
        if (StringUtils.isNotBlank(dataUrl)) {
            dataUrl = SharedVarsUtil.delInnerVars(dataUrl, null);
        }
        return checkPerm(request, getUserPermIds(request), null, dataUrl);
    }

    public static boolean checkPageIdPerm(HttpServletRequest request, String pageId) {
        return checkPerm(request, getUserPermIds(request), pageId, null);
    }

    /**
     * 检查pageId或dataUrl权限是否存在
     * 
     * @Title checkPerm
     * @author 吕凯
     * @date 2019年9月21日 上午9:04:53
     * @param request
     * @param userPermIds
     * @param pageId
     * @param dataUrl
     * @return boolean
     */
    public static boolean checkPerm(HttpServletRequest request, Set<String> userPermIds, String pageId, String dataUrl) {
        SysMenuModel childPermModle = getPermModel(pageId, dataUrl);

        if (childPermModle != null && SystemStaticParams.PERMISSION_NO != childPermModle.getPermType()) { // 未设置属性不判断权限且权限管理中有
            if (SystemStaticParams.PERMISSION_LOGIN_NO_CHECK == childPermModle.getPermType()) { // 登录权限（登录后即可使用的权限）
                if (Web.Util.getSessionUserId(request) == null) { // 未登录
                    return false;
                }
            } else if (SystemStaticParams.PERMISSION_CHECK == childPermModle.getPermType()) {
                if (userPermIds != null) {
                    if (!userPermIds.contains(childPermModle.getId() + "")) { // 用户没有该权限则移除不显示
                        return false;
                    }

                } else { // 用户权限为空，则无权限
                    return false;
                }
            }
        }
        return true;
    }

    public static boolean checkElePerm(HttpServletRequest request, Element childEle, String pageId, String dataUrl) {
        return checkElePerm(request, getUserPermIds(request), childEle, pageId, dataUrl);
    }

    /**
     * 检查ele元素是否存在某权限
     * 
     * @Title checkElePerm
     * @author 吕凯
     * @date 2019年9月21日 上午8:58:33
     * @param request
     * @param userPermIds
     * @param childEle
     * @param pageId
     *            pageId属性值，对应权限表中的pageId，唯一
     * @param dataUrl
     *            链接地址，可能不唯一
     * @return boolean
     */
    public static boolean checkElePerm(HttpServletRequest request, Set<String> userPermIds, Element childEle, String pageId,
            String dataUrl) {
        if (!childEle.hasAttr("noperm")) { // 未设置属性不判断权限
            SysMenuModel childPermModle = getPermModel(pageId, dataUrl);

            if (childEle.hasAttr("unionAdd")) { // 联合权限，与后面的权限验证必须同时满足
                if (childEle.attr("unionAdd").equals("false")) {
                    return false;
                }
                if (childPermModle == null) {
                    return false;
                }
            } else if (childEle.hasAttr("unionOr")) { // 联合权限，与后面的权限验证满足一个即可
                if (childEle.attr("unionOr").equals("true")) {
                    return true;
                }
                if (childPermModle == null) {
                    return false;
                }

            }
            return checkPerm(request, userPermIds, pageId, dataUrl);
        }
        return true;
    }

    /**
     * 获取pageId或dataUrl对应的权限对象
     * 
     * @Title getPermModel
     * @author 吕凯
     * @date 2019年9月21日 上午9:04:20
     * @param pageId
     * @param dataUrl
     * @return SysMenuModel
     */
    private static SysMenuModel getPermModel(String pageId, String dataUrl) {
        boolean hasPageId = false;
        if (StringUtils.isNotBlank(pageId)) {
            hasPageId = true;
        }
        SysMenuModel childPermModle = null;
        if (hasPageId) {
            childPermModle = PermissionUtil.getPermByPageId(pageId); // 存在pageId对应的权限
        } else {
            childPermModle = PermissionUtil.getPermModleByUrl(dataUrl); // 获取url在权限中的映射（前提是不同权限的url唯一）
        }
        return childPermModle;
    }

}
